package com.tidu.manager;

import com.tidu.entry.DataSourceMetadata;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import org.springframework.stereotype.Service;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

@Service
public class DataSourceManager {
    // 根据JDBC URL缓存数据源
    private static final Map<String, HikariDataSource> dataSourceCache = new HashMap<>();
    
    // 私有构造器防止实例化
    private DataSourceManager() {}
    
    /**
     * 获取数据库连接
     * 
     * @param metadata 数据源元数据
     * @return 数据库连接
     * @throws SQLException
     */
    public Connection getConnection(DataSourceMetadata metadata) throws SQLException {
        String cacheKey = metadata.getJdbcUrl() + "|" + metadata.getUsername();
        
        // 如果缓存中有，直接返回
        if (dataSourceCache.containsKey(cacheKey)) {
            return dataSourceCache.get(cacheKey).getConnection();
        }
        
        // 创建新的数据源
        HikariDataSource dataSource = createDataSource(metadata);
        dataSourceCache.put(cacheKey, dataSource);
        
        return dataSource.getConnection();
    }
    
    /**
     * 创建Hikari数据源
     */
    private HikariDataSource createDataSource(DataSourceMetadata metadata) {
        HikariConfig config = new HikariConfig();
        
        // 设置驱动类名
        config.setDriverClassName(getDriverClassName(metadata.getDbType()));
        
        // 设置连接参数
        config.setJdbcUrl(metadata.getJdbcUrl());
        config.setUsername(metadata.getUsername());
        config.setPassword(metadata.getPassword());
        
        // 通用连接池配置
        config.setMaximumPoolSize(5); // 最大连接数
        config.setMinimumIdle(1);     // 最小空闲连接
        config.setConnectionTimeout(30000); // 连接超时时间(毫秒)
        config.setIdleTimeout(600000);      // 空闲连接超时时间(毫秒)
        config.setMaxLifetime(1800000);     // 连接最大生命周期(毫秒)
        
        // DB特定优化
        applyDbSpecificConfig(metadata.getDbType(), config);
        
        return new HikariDataSource(config);
    }
    
    /**
     * 根据数据库类型获取驱动类名
     */
    private String getDriverClassName(String dbType) {
        switch (dbType.toLowerCase()) {
            case "mysql": return "com.mysql.cj.jdbc.Driver";
            case "oracle": return "oracle.jdbc.OracleDriver";
            case "postgresql": return "org.postgresql.Driver";
            case "sqlserver": return "com.microsoft.sqlserver.jdbc.SQLServerDriver";
            default: throw new IllegalArgumentException("不支持的数据库类型: " + dbType);
        }
    }
    
    /**
     * 应用数据库特定的配置
     */
    private void applyDbSpecificConfig(String dbType, HikariConfig config) {
        switch (dbType.toLowerCase()) {
            case "mysql":
                config.addDataSourceProperty("cachePrepStmts", "true");
                config.addDataSourceProperty("prepStmtCacheSize", "250");
                config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
                break;
                
            case "oracle":
                config.addDataSourceProperty("oracle.jdbc.timezoneAsRegion", "false");
                config.setConnectionTestQuery("SELECT 1 FROM DUAL");
                break;
                
            case "postgresql":
                config.setConnectionTestQuery("SELECT 1");
                config.addDataSourceProperty("tcpKeepAlive", "true");
                break;
                
            case "sqlserver":
                config.setConnectionTestQuery("SELECT 1");
                config.addDataSourceProperty("trustServerCertificate", "true");
                break;
        }
    }
    
    /**
     * 关闭所有数据源
     */
    public void shutdown() {
        for (HikariDataSource dataSource : dataSourceCache.values()) {
            if (dataSource != null && !dataSource.isClosed()) {
                dataSource.close();
            }
        }
        dataSourceCache.clear();
    }
}